﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Functions.cs" company="Collaboris Ltd.">
//   Copyright (c) Collaboris Ltd. All rights Reserved.
// </copyright>
// <summary>
//   Defines the Globals type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Collaboris.Saf.Engine.Factory.Spring
{
    using System;
    using System.Globalization;
    using System.Web;

    using global::Spring.Collections;
    using global::Spring.Expressions;

    using Utils;

    /// <summary>
    /// Contains Functions used by the Actions.
    /// </summary>
    public static class Functions
    {
        public static object Eval(string expression)
        {
            // If this has a place holder that hasnt been resolved.
            if (HasPlaceHolder(expression))
                return null;

            // Ok, we have no placeholder so have a string.
            string parsedExpression = ParseAllExpressions(expression, new ListSet());
            if (string.IsNullOrEmpty(parsedExpression))
                return null;

            string newParsedExpression = parsedExpression;
            // if we have XML in here
            if (parsedExpression.StartsWith("&lt;") && 
                (parsedExpression.EndsWith("&gt;") || parsedExpression.EndsWith(">")))
            {
                newParsedExpression = HttpUtility.HtmlDecode(parsedExpression);
            }

            object rValue = null;
            if (newParsedExpression.StartsWith("<") && newParsedExpression.EndsWith(">"))
            {
                try
                {
                    // try to deserialise it here
                    rValue = SerialisationHelper.Deserialize(newParsedExpression);
                }
                catch
                {
                }

            }

            // it looked like Xml but obviously wasn't something that could be serialised.
            if (rValue != null)
                return rValue;

            // ok so now expression.
            return parsedExpression;
        }

        private static bool HasPlaceHolder(string strVal)
        {
            int index = strVal.IndexOf(Globals.PlaceHolderPlaceholderPrefix);
            while (index != -1)
            {
                int num2 = strVal.IndexOf(
                    Globals.PlaceHolderPlaceholderSuffix, (int)(index + Globals.PlaceHolderPlaceholderPrefix.Length));
                if (num2 != -1)
                {
                    int startIndex = index + Globals.PlaceHolderPlaceholderPrefix.Length;
                    string element = strVal.Substring(startIndex, num2 - startIndex);
                    if (!string.IsNullOrEmpty(element))
                        return true;
                    else
                        return false;
                }
            }

            return false;
        }

        private static string ParseAllExpressions(string strVal, ISet visitedPlaceholders)
        {
            int index = strVal.IndexOf(Globals.ExpressionPlaceholderPrefix);
            while (index != -1)
            {
                int num2 = strVal.IndexOf(Globals.ExpressionPlaceholderSuffix, (int)(index + Globals.ExpressionPlaceholderPrefix.Length));
                if (num2 != -1)
                {
                    int startIndex = index + Globals.ExpressionPlaceholderPrefix.Length;
                    string element = strVal.Substring(startIndex, num2 - startIndex);
                    if (visitedPlaceholders.Contains(element))
                    {
                        throw new ApplicationException(string.Format(CultureInfo.InvariantCulture, "Circular placeholder reference '{0}'.", new object[] { element }));
                    }

                    visitedPlaceholders.Add(element);
                    //string str2 = this.ResolvePlaceholder(element, properties, this.environmentVariableMode);
                    element = element.Replace(@"&quot;", "'");
                    string str2 = ExpressionEvaluator.GetValue(null, element).ToString();
                    if (str2 != null)
                    {
                        str2 = ParseAllExpressions(str2, visitedPlaceholders);
                        //if (this.logger.IsDebugEnabled)
                        //{
                        //    this.logger.Debug(string.Format(CultureInfo.InvariantCulture, "Resolving placeholder '{0}' to '{1}'.", new object[] { element, str2 }));
                        //}
                        strVal = strVal.Substring(0, index) + str2 + strVal.Substring(num2 + 1);
                        index = strVal.IndexOf(Globals.ExpressionPlaceholderPrefix, (int)(index + str2.Length));
                    }
                    else
                    {
                        //if (!this.ignoreUnresolvablePlaceholders)
                        //{
                            throw new ApplicationException(string.Format(CultureInfo.InvariantCulture, "Could not resolve placeholder '{0}'.", new object[] { element }));
                        //}

                        return strVal;
                    }

                    visitedPlaceholders.Remove(element);
                }
                else
                {
                    index = -1;
                }
            }

            return strVal;
        }
    }
}